using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace MoEngine
{
    public class ChildrenWindowCollection : WindowCollection<Window>
    {
    }

    public abstract class WindowBase : CoreComponentDrawable
    {
        #region Layout
        public abstract Vector2 Position
        {
            get;
        }

        public abstract Vector2 Size
        {
            get;
        }

        public float AspectRatio
        {
            get { return (Size.Y == 0 ? float.MaxValue : Size.X / Size.Y); }
        }

        public abstract Vector2 GlobalPosition
        {
            get;
        }

        public event EventHandler GlobalPoistionChanged;

        protected virtual void OnGlobalPositionChanged()
        {
            if (GlobalPoistionChanged != null)
                GlobalPoistionChanged(this, null);
        }

        public event EventHandler SizeChanged;

        protected virtual void OnSizeChanged()
        {
            if (SizeChanged != null)
                SizeChanged(this, null);
        }

        #endregion

        public abstract GraphicsDevice Device { get;}

        public int Layer
        {
            get { return DrawOrder; }
            set { DrawOrder = value; }
        }

        public event EventHandler LayerChanged;

        #region Constructor

        public WindowBase()
        {
            DrawOrderChanged += new EventHandler(OnDrawOrderChanged);
        }

        void OnDrawOrderChanged(object sender, EventArgs e)
        {
            EventHandler tempEvent = LayerChanged;
            if (tempEvent != null)
                tempEvent(this, null);
        }

        #endregion

        #region Children Windows

        protected ChildrenWindowCollection m_ChildWnds = new ChildrenWindowCollection();
        
        public void AddChild(Window childWnd)
        {
            // TODO: may need to check to make sure it's not called after child window constructed
            // i.e. childWnd.Parent == null / == this?

            m_ChildWnds.Add(childWnd);
            childWnd.OnAttachedToParent(this);
        }

        // TODO: remove child

        #endregion

        #region Update & Draw

        /// <summary>
        /// Update self and all children
        /// </summary>
        /// <param name="time"></param>
        public override void Update(GameTime time)
        {
            // validate layout
            ValidateLayout();

            // update self
            UpdateWindow(time);

            // update children
            m_ChildWnds.UpdateAll(time);
        }

        public virtual void ValidateLayout() { }

        protected virtual void UpdateWindow(GameTime time) { }

        /// <summary>
        /// Draw self and all children
        /// </summary>
        /// <param name="time"></param>
        public override void Draw(GameTime time)
        {
            // validate layout
            ValidateLayout();

            // draw self
            DrawWindow(time);

            // draw children
            m_ChildWnds.DrawAll(time);

            // draw self on top of children
            PostDrawWindow(time);
        }

        protected virtual void DrawWindow(GameTime time) { }
        protected virtual void PostDrawWindow(GameTime time) { }

        #endregion

        public abstract MasterWindow MasterWnd { get; }

        public abstract bool HandleMouseInput(MouseEventType evtType, MouseButtons button, Point mousePos, InputEventArgs evtArgs);

    }
}
